package com.zlyx.easy.core.event;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;

import com.zlyx.easy.core.annotations.ApplicationBean;
import com.zlyx.easy.core.annotations.SpringBean;
import com.zlyx.easy.core.utils.LogUtils;
import com.zlyx.easy.core.utils.SpringUtils;

/**
 * @Auth 赵光
 * @Desc
 * @2018年12月12日 下午5:12:03
 */
@SpringBean(todo = { "系统刷新事件加载工厂" })
public class ApplicationEventFactory implements ApplicationListener<ApplicationEvent> {

	private boolean ClassPathChangedEventStatus = Boolean.TRUE;

	private boolean ContextRefreshedEventStatus = Boolean.TRUE;

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		String eventName = event.getClass().getSimpleName();
		if ("ClassPathChangedEvent".equals(eventName) && ClassPathChangedEventStatus) {
			ClassPathChangedEventStatus = Boolean.FALSE;
			doClassPathChangedEvent();
		} else if ("ContextRefreshedEvent".equals(eventName) && ContextRefreshedEventStatus) {
			ContextRefreshedEventStatus = Boolean.FALSE;
			doContextRefreshedEvent();
		}
	}

	/**
	 * 上下文刷新事件
	 * 
	 * @throws Exception
	 */
	private void doContextRefreshedEvent() {
		List<IHandlerOnRefreshed> beans = SpringUtils.getBeansByType(IHandlerOnRefreshed.class);
		ApplicationContext context = SpringUtils.getApplicationContext();
		if (beans != null && !beans.isEmpty()) {
			if (beans.size() == 1) {
				try {
					beans.get(0).doOnRefreshed(context);
				} catch (Exception e) {
					LogUtils.err(e);
				}
				return;
			}
			ApplicationBean beanAnnotation = null;
			IHandlerOnRefreshed handler = null;
			Order orderAnnotation = null;
			int o = 5;
			for (int order = 0; order <= 10; order++) {
				for (int i = 0; i < beans.size(); i++) {
					try {
						handler = beans.get(i);
						orderAnnotation = AnnotationUtils.findAnnotation(handler.getClass(), Order.class);
						beanAnnotation = handler.getClass().getAnnotation(ApplicationBean.class);
						if (orderAnnotation != null) {
							o = orderAnnotation.value();
						} else if (beanAnnotation != null) {
							o = beanAnnotation.order();
						}
						if (beanAnnotation == null || order == 5 || o <= order) {
							handler.doOnRefreshed(context);
							beans.remove(i);
						}
					} catch (Exception e) {
						LogUtils.err(e);
						beans.remove(i);
					}
				}
			}
		}
	}

	/**
	 * 热加载事件
	 * 
	 * @throws Exception
	 */
	private void doClassPathChangedEvent() {
		List<IHandlerOnChanged> beans = SpringUtils.getBeansByType(IHandlerOnChanged.class);
		ApplicationContext context = SpringUtils.getApplicationContext();
		if (beans != null) {
			for (IHandlerOnChanged handler : beans) {
				try {
					handler.doOnChanged(context);
				} catch (Exception e) {
					LogUtils.err(e);
				}
			}
		}
	}
}
